﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;


namespace OpenShape
{
    static class CStatics
    {
        //분석을 위한 인덱스 저장 스트링
        public static string AnalyDBF;

        #region == Cluster 군집분석 Euclidean 거리(거리측정) + 최장연결법 ==
        public class ACluster
        {
            //멤버선언부
            public double[,] AnalyIndx;
            public double[,] source;
            public double[,] dis_Analysis;
            public int Vcount; // dt에서 선택된 필드갯수 
            public int Vnameidx;  // 라벨의 dt.idx

            public ACluster(string[] idx)
            {
                Vcount = idx.Length - 1;
                
                AnalyIndx = new double[Vcount, 3]; // [,0]-dt.idx ; [,1] -  average ; [,2] - stdev
                
                // Vcount = 6
                MakeAnalyIndx(idx);
                
                
            }


            //메소드선언부
            /// <summary>
            /// 평균(Aver)  - analy1
            /// 표준편차(Stdev) - analy2
            /// 표준화(Z) - analy3
            /// Euclidean 거리 (D) - analy4
            /// 최장연결법(FN) - analy5
            /// </summary>

            //AnalyIndx 배열 설정(문자->숫자인덱스 [i,0]
            public void MakeAnalyIndx(string[] temp)
            {
                for (int i = 0; i < Vcount; i++)
                {
                   this.AnalyIndx[i, 0] = Convert.ToInt32(temp[i]);
                }

                //라벨인덱스
                Vnameidx = Convert.ToInt32(temp[Vcount]);
            }



            //평균(Aver) +  표준편차(STdev)
            public void Analy1(DataTable odt)
            {
                DataTable dt = odt;

                //평균
                for (int i = 0; i < Vcount; i++)
                {
                    double aver = 0;
                    for (int j = 0; j < dt.Rows.Count; j++)
                    {
                        aver += Convert.ToDouble(dt.Rows[j][Convert.ToInt32(AnalyIndx[i, 0])]);
                    }
                    AnalyIndx[i, 1] = aver / dt.Rows.Count;
                 
                }

                //표준편차
                for (int i = 0; i < Vcount; i++)
                {
                    double dev1 = 0;
                    double dev2 = 0;
                    double Value=0;
                    int n = dt.Rows.Count;
                    for (int j = 0; j < dt.Rows.Count; j++)
                    {
                        Value =Convert.ToDouble(dt.Rows[j][Convert.ToInt32(AnalyIndx[i, 0])]);
                        dev1 += Math.Pow(Value, 2);
                        dev2 += Value;
                    }
                    AnalyIndx[i, 2] = Math.Sqrt((n*dev1 - Math.Pow (dev2,2))/(n*(n-1)));
                }

                // 거리계산용 데이터 : Z-Score 값
                source = new double[dt.Rows.Count, Vcount]; // [27,6]

                for (int i = 0; i < Vcount; i++)
                {
                    double Value=0;
                    for (int j = 0; j < dt.Rows.Count; j++)
                    {
                        Value =Convert.ToDouble(dt.Rows[j][Convert.ToInt32(AnalyIndx[i, 0])]);
                        source[j, i] = (Value - AnalyIndx[i, 1]) / AnalyIndx[i, 2];
                    }
                }

                //

                dis_Analysis = new double[dt.Rows.Count, dt.Rows.Count]; // [27,27]

                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    dis_Analysis[i, i] = 1;
                    for (int j = i + 1; j < dt.Rows.Count; j++)
                    {
                        dis_Analysis[j, i] = -99;
                        double temp_cal = 0;
                        for (int k = 0; k < Vcount; k++)
                        {
                            temp_cal += Math.Pow((source[i, k] - source[j, k]), 2);
                        }
                        dis_Analysis[i, j] = Math.Sqrt(temp_cal);
                    }
                }

            }

        }
        #endregion
    }
}
